package es.udc.emarketapp.http.controller.actions.categories;

import es.udc.emarketapp.emarket.model.category.vo.CategoryVO;
import es.udc.emarketapp.emarket.model.categoryFacade.CategoryFacade;
import es.udc.emarketapp.emarket.model.productFacade.ProductFacade;
import es.udc.emarketapp.emarket.model.categoryFacade.vo.CategoryChunkVO;
import es.udc.emarketapp.emarket.model.productFacade.vo.ProductChunkVO;
import es.udc.emarketapp.http.view.actionForms.FindProductsForm;
import es.udc.fbellas.j2ee.util.exceptions.InstanceNotFoundException;
import es.udc.fbellas.j2ee.util.exceptions.InternalErrorException;
import es.udc.fbellas.j2ee.util.struts.action.DefaultAction;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

public class CategoriesTreeAction extends DefaultAction {

    public ActionForward doExecute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException, InternalErrorException {

        /* Get data. */

        FindProductsForm findForm = (FindProductsForm) form;
        Long idCat = findForm.getIdCat();

        //long idCat = Integer.parseInt(request.getParameter("idCat"));

        /* Do action. */
        /*
        return doFindSubcategoriesAndProducts(mapping, idCat,
        1, 10, request);
         */
        return doFindSubcategoriesAndProducts(mapping, idCat,
                findForm.getStartIndex(), findForm.getCount(), request);

    }

    private ActionForward doFindSubcategoriesAndProducts(
            ActionMapping mapping, Long idCat, int startIndex,
            int count, HttpServletRequest request)
            throws InternalErrorException {

        ActionMessages errors = new ActionMessages();

        ProductFacade productsFacade = new ProductFacade();
        CategoryFacade categoryFacade = new CategoryFacade();

        CategoryVO categoryVO = null;

        try {
            categoryVO = categoryFacade.findCategoryById(idCat);
            List<CategoryVO> listCats = categoryFacade.getCategoryRoute(idCat);
            HttpSession session = request.getSession(true);
            session.setAttribute("currentCategories", listCats);
            session.setAttribute("catFather", idCat);
            session.setAttribute("idcat", idCat);

        } catch (InstanceNotFoundException e) {

            errors.add("identifier",
                    new ActionMessage("ErrorMessages.category.notFound"));
            saveErrors(request, errors);
        }

        List<CategoryVO> currentCat = new ArrayList<CategoryVO>();

        CategoryVO cat = categoryVO;

        while (cat.getCatPadre() > 0) {
            CategoryVO catPadre;
            try {
                catPadre = categoryFacade.findCategoryById(cat.getCatPadre());
                currentCat.add(cat);
                cat = catPadre;

            } catch (InstanceNotFoundException e) {
                errors.add("identifier",
                        new ActionMessage("ErrorMessages.category.notFound"));
                saveErrors(request, errors);
            }
        }


        //instertamos las categorias padres en orden
        List<CategoryVO> currentCatOrd = new ArrayList<CategoryVO>();
        while (!currentCat.isEmpty()) {
            int index = currentCat.size();
            currentCatOrd.add(currentCat.get(index - 1));
            currentCat.remove(index - 1);
        }

        // se introduce en la request la lista de categorias que
        // represtentan la ruta de la categoria actual
        request.setAttribute("categories", currentCatOrd);
        request.setAttribute("idCat", categoryVO.getCatPadre());
        request.setAttribute("idSelectCat", categoryVO.getIdCat());
        request.setAttribute("nomCat", categoryVO.getNomCat());
        request.setAttribute("currentCategories", currentCatOrd);

        // se introduce en la request la lista de categorias que
        // represtentan las categorias hijas de la actual
        CategoryChunkVO categoryChunk = categoryFacade.getCategorySons(categoryVO.getIdCat(), 1, 50);
        request.setAttribute("categorySons", categoryChunk.getCategoryVOs());


        CategoryChunkVO categoriaChunkVO =
                categoryFacade.getCategorySons(idCat, startIndex, count);

        if (categoriaChunkVO.getCategoryVOs().size() > 0) {

            request.setAttribute("categorySons",
                    categoriaChunkVO.getCategoryVOs());

        } else {
            System.out.println("no hay cat sons");
        }


        ProductChunkVO productChunkVO =
                productsFacade.findByCategory(idCat, startIndex, count);

        if (productChunkVO.getProductVOs().size() > 0) {

            request.setAttribute("products",
                    productChunkVO.getProductVOs());
        }



        // Generate parameters for previous and next links.

        Map previousLinkParameters = getPreviousLinkParameters(
                idCat, startIndex, count);

        if (previousLinkParameters != null) {
            request.setAttribute("previous", previousLinkParameters);
        }

        if (productChunkVO.getExistMoreProducts()) {
            Map nextLinkParameters = getNextLinkParameters(idCat,
                    startIndex, count);
            request.setAttribute("next", nextLinkParameters);
        }



        /* Return ActionForward. */
        return mapping.findForward("FindSubcategoriesAndProductSuccess");
    }

    private Map getPreviousLinkParameters(long identifier,
            int startIndex, int count) {

        Map linkAttributes = null;

        if ((startIndex - count) > 0) {

            linkAttributes = getCommonPreviousNextLinkParameters(
                    identifier, startIndex, count);
            linkAttributes.put("startIndex", new Integer(startIndex - count));
        }

        return linkAttributes;

    }

    private Map getNextLinkParameters(Long identifier,
            int startIndex, int count) {

        Map linkAttributes = getCommonPreviousNextLinkParameters(
                identifier, startIndex, count);
        linkAttributes.put("startIndex", new Integer(startIndex + count));

        return linkAttributes;
    }

    private Map getCommonPreviousNextLinkParameters(Long identifier,
            int startIndex, int count) {

        Map linkAttributes = new HashMap();

        linkAttributes.put("idCat", identifier);
        linkAttributes.put("count", new Integer(count));

        return linkAttributes;

    }
}
